package com.hkd.system.service.sysuser.Impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hkd.common.core.constants.HttpConstants;
import com.hkd.common.core.domain.LoginUser;
import com.hkd.common.core.domain.R;
import com.hkd.common.core.domain.vo.LoginUserVo;
import com.hkd.common.core.enums.ResultCode;
import com.hkd.common.core.enums.UserIdentity;
import com.hkd.common.security.exception.ServiceException;
import com.hkd.common.security.service.TokenService;
import com.hkd.system.domain.sysuser.dto.SysUserSaveDTO;
import com.hkd.system.domain.sysuser.SysUser;
import com.hkd.system.mapper.sysuser.SysUserMapper;
import com.hkd.system.service.sysuser.ISysUserService;
import com.hkd.system.utils.BCryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
@RefreshScope
public class SysUserServiceImpl implements ISysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}")
    private String secret;

    /*@Autowired
    private HttpServletResponse response;*/

    /**
     * 登录
     * @param userAccount 用户名
     * @param password 密码
     * @return String token
     */
    @Override
    public R login(String userAccount, String password) {
        log.info("account: "+userAccount);
        log.info("password: "+password);

        //1、查询信息
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        SysUser sysUser = sysUserMapper.selectOne
                (queryWrapper.select(SysUser::getUserId,SysUser::getUserPassword,SysUser::getNickName)
                        .eq(SysUser::getUserAccount, userAccount));

        //2、校验用户信息
        if (sysUser == null) {
            return R.failed(ResultCode.USER_NOT_EXISTS);
        }

        //3、校验密码
        if (!BCryptUtils.matchesPassword(password, sysUser.getUserPassword())) {
            return R.failed(ResultCode.LOGIN_FAILED);
        }

        //4、生成token
        log.info("登录成功","userAccount:{}",userAccount);
        String token = tokenService.createToken(sysUser.getUserId(), secret, UserIdentity.ADMIN.getValue(),sysUser.getNickName());

        //4、登录成功
        return R.success(token);
    }

    /**
     * 添加用户
     * @param sysUserSaveDTO 用户信息
     * @return
     */
    @Override
    public R add(SysUserSaveDTO sysUserSaveDTO) {
        //1、校验用户信息
        List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount, sysUserSaveDTO.getUserAccount()));
        if (!CollectionUtils.isEmpty(sysUserList)) {
            //打印日志
            log.error(ResultCode.USER_EXISTS.getMessage());
            //返回错误信息
            throw new ServiceException(ResultCode.USER_EXISTS);
        }

        //2、保存用户信息
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setUserPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
        int insert = sysUserMapper.insert(sysUser);

        //3、校验是否成功
        if(insert <= 0){
            log.warn(ResultCode.FAILED_SYSUSER_ADD.getMessage());
            return R.failed(ResultCode.FAILED_SYSUSER_ADD);
        }
        return R.success();
    }

    /**
     * 获取用户信息
     * @param token token
     * @return LoginUserVo 用户信息
     */
    @Override
    public R getInfo(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        //1、解析token
        LoginUser loginUser = tokenService.getLoginUser(token, secret);

        //2、校验token
        if(loginUser == null){
            log.warn(ResultCode.FAILED_TOKEN_GET_INFO.getMessage());
            return R.failed(ResultCode.FAILED_TOKEN_GET_INFO);
        }
        //3、查询用户信息
        LoginUserVo loginUserVo = new LoginUserVo();
        loginUserVo.setNickName(loginUser.getNickName());
        Date date = new Date();
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");

        //4、返回用户信息
        return R.success(loginUserVo,"您好！ "+loginUser.getNickName()+" 北京时间:"+timeFormat.format(date));
    }

    /**
     * 退出登录
     * @param token token
     * @return
     */
    @Override
    public R logout(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        //1、解析token
        Boolean result = tokenService.deleteLoginUser(token, secret);
        if(!result ){
            log.warn(ResultCode.FAILED_DELETE.getMessage());
            return R.failed(ResultCode.FAILED_DELETE.getCode(),ResultCode.FAILED_DELETE.getMessage());
        }
        return R.success();
    }
}
